package cn.wk.service.impl;

import cn.wk.exception.GlobalException;
import cn.wk.service.IVerifyCodeService;
import cn.wk.util.StrUtils;
import cn.wk.util.VerifyCodeUtils;
import cn.wk.utils.ValidUtils;
import cn.wk.dto.SendSmsDto;
import cn.wk.vo.SmsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.zip.Inflater;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 图片验证码
     * @param imageCodeKey
     * @return
     */
    @Override
    public String imageCode(String imageCodeKey) {
        //先进行判断参数
        ValidUtils.assertNotNull(imageCodeKey,"参数错误，请刷新页面重试");
        //然后生成随机数作为验证码
        String code = UUID.randomUUID().toString().substring(0,4);
        System.out.println(code);
        //然后把传进来的参数作为key，验证码作为value 并设置过期时间
        redisTemplate.opsForValue().set(imageCodeKey,code,10, TimeUnit.MINUTES);
        //然后调用工具生成图片的base64 返回
        return VerifyCodeUtils.VerifyCode(150, 40, code);
    }

    /**
     * 发送手机验证码
     * @param sendSmsVo
     */
    @Override
    public void sendSmsCode(SendSmsDto sendSmsVo) {
        //验证数据
        String imageCode = sendSmsVo.getImageCode();
        String imageCodeKey = sendSmsVo.getImageCodeKey();
        String mobile = sendSmsVo.getMobile();
        ValidUtils.assertNotNull(imageCode,"请输入图片验证码");
        ValidUtils.assertNotNull(imageCodeKey,"参数错误，请刷新页面");
        ValidUtils.assertNotNull(mobile,"请输入手机号");
        //比较图片验证码是否输入正确
        String imageCodeFromRedis = (String)redisTemplate.opsForValue().get(imageCodeKey);
        ValidUtils.assertNotNull(imageCodeFromRedis,"图片验证码已经过期");
        //ValidUtils.assertEq(imageCode,imageCodeFromRedis,"图片验证码输入错误");
        if(!imageCode.toLowerCase().equals(imageCodeFromRedis.toLowerCase())){
            throw new GlobalException("图片验证码输入错误");
        }
        //然后还有就是看redis中是否有该验证码没有使用
        SmsVo redisCode = (SmsVo)redisTemplate.opsForValue().get("sms:" + mobile);
        //一分钟不能多次发送验证码
        long timeMillis = System.currentTimeMillis();
        //准备验证码
        String code = null;
        if(redisCode != null){
            if((timeMillis-redisCode.getTime())<    60*1000){
                throw new GlobalException("请勿一分钟内多次获取验证码");
            }
            //这里是redis中有验证码 而且也过了一分钟 应该继续使用redis中的验证码
            code = redisCode.getCode();
        }else {
            //准备验证码
            code = StrUtils.getRandomString(4);
        }
        //把验证码保存到redis中，key是常量加手机号，value是验证码加上时间戳(这里封装成了一个对象),五分钟过期时间
        redisTemplate.opsForValue().set("sms:"+mobile,new SmsVo(code,timeMillis),5,TimeUnit.MINUTES);
        //发送验证码
        log.info("验证码为："+code);
        //保存到数据库
        log.info("验证码已经保存到数据库");

    }
}
